package views.components;

import java.util.ArrayList;

import utils.MessageUtils;
import utils.ReflectionUtils;

import com.vaadin.addon.jpacontainer.EntityItem;
import com.vaadin.addon.jpacontainer.JPAContainer;
import com.vaadin.addon.jpacontainer.JPAContainerFactory;
import com.vaadin.addon.jpacontainer.util.HibernateLazyLoadingDelegate;
import com.vaadin.data.Property;
import com.vaadin.data.Validatable;
import com.vaadin.data.Validator;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.data.util.converter.Converter.ConversionException;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomField;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;

import config.Parameters;
import dao.interfaces.IBase;

@SuppressWarnings("serial")
public class SelectorManyToOne extends CustomField<IBase> {

	private Table table;
	private Class<IBase> myClass;
	private JPAContainer<IBase> jpaContainer;

	public SelectorManyToOne(Class<IBase> myClass) {

		this.myClass = myClass;

		table = new Table();
		table.setSizeUndefined();
		table.setImmediate(true);
		table.setSelectable(true);
		table.setNullSelectionAllowed(true);

		jpaContainer = JPAContainerFactory.make(myClass,
				Parameters.DB_DATA_SOURCE);
		jpaContainer.getEntityProvider().setLazyLoadingDelegate(
				new HibernateLazyLoadingDelegate());

		table.setContainerDataSource(jpaContainer);
		table.setPageLength(Math.min(jpaContainer.size(), 10));

		// agafe les columnes que seran visibles per esta @view en myClass

		ArrayList<String> columnes = ReflectionUtils.getViewFields(
				myClass, "selector");

		// anyadim la columna generada del comboBox
		// accio que realitzara el boto de executar
		table.setVisibleColumns(columnes.toArray());

		// creem les cabeceres de les columnes de la tabla internacionalitzades
		String[] headers = new String[columnes.size()];
		for (int i = 0; i < columnes.size(); i++)
			headers[i] = MessageUtils.getI18n(columnes.get(i));

		table.setColumnHeaders(headers);

		table.addValidator(new Validator() {

			@Override
			public void validate(Object value) throws InvalidValueException {
				if (table.getValue() != null) {
					setRequired(false);
				} else {
					setRequired(true);
				}
			}
		});
	}

	@Override
	public void validate() throws InvalidValueException {
		
		if (getValue() != null) {
			setRequired(false);
		} else {
			setRequired(true);
		}
	}
	
	@Override
	public void setValue(IBase newFieldValue)
			throws com.vaadin.data.Property.ReadOnlyException,
			ConversionException {
		super.setValue(newFieldValue);
		setIbase(newFieldValue);
	}

	@Override
	public IBase getValue() {

		Object value = table.getValue();
		EntityItem<IBase> item = jpaContainer.getItem(value);
		IBase entity = item != null ? item.getEntity() : null;

		return entity;
	}

	private void setIbase(IBase ibase) {
		table.setValue(ibase != null ? ibase.getId() : null);
	}

	@Override
	public void setPropertyDataSource(Property newDataSource) {
		super.setPropertyDataSource(newDataSource);
		setIbase((IBase) newDataSource.getValue());
	}

	@Override
	public Property<Object> getPropertyDataSource() {

		Property<Object> propertyDataSource = super.getPropertyDataSource();
		Object value = getValue();
		propertyDataSource.setValue(value);

		return propertyDataSource;
	}

	@Override
	protected Component initContent() {
		VerticalLayout root = new VerticalLayout();
		setCaption(MessageUtils.getI18n(myClass.getSimpleName()));
		root.addComponent(table);
		root.setSizeUndefined();
		return root;
	}

	@Override
	public Class<IBase> getType() {
		return myClass;
	}

}
